package com.mall.b2c.domain.member;

import java.math.BigDecimal;
import java.util.Date;
import java.util.Set;

import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.PrePersist;
import javax.persistence.Table;
import javax.persistence.Transient;

import net.sf.json.JSONObject;

import org.apache.commons.lang3.StringUtils;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.mall.b2c.domain.goods.GoodsDomain;
import com.mall.b2c.domain.order.CartDomain;
import com.mall.common.domain.AreaDomain;
import com.mall.common.domain.BaseEntity;
import com.mall.common.util.VerifyUtil;

/**
 * 实体 - 会员
 */
/**
 * @author Administrator
 *
 */
@Entity
@Table(name = "b2c_member")
public class MemberDomain extends BaseEntity {

	private static final long serialVersionUID = -4768775448553485583L;

	private String username;// 用户名
	private String email;// 邮箱
	private String password;// 密码
	private Integer point;// 积分
	private BigDecimal deposit;//余额
	private Integer loginFailureCount;// 连续登录失败的次数
	private Boolean isAccountEnabled; // 账号是否启用
	private Boolean isAccountLocked; // 帐号是否锁定,用于连续登录失败loginFailureCount次数后，锁定帐号
	private Date lockedDate;// 账号锁定日期
	private String registerIp;// 注册IP
	private String loginIp;// 最后登录IP
	private Date loginDate;// 最后登录日期
	private Boolean sex;// 性别
	private String mobile;// 手机号码
	private String phone;// 电话号码
	private String qq;// qq号码
	private Date birthday;
	private String name;// 昵称
	@JsonIgnore private AreaDomain area;// 地区
	private String address;// 地址
	private String zipCode;// 邮编
	
	private String emailVerifyCode;//邮箱验证码
	private String smsVerifyCode;//短信验证码
	
	@JsonIgnore private MemberDomain inviter;
	@JsonIgnore private CartDomain cart;
	@JsonIgnore private Set<ReceiverDomain> receiverSet;// 收货地址
	@JsonIgnore private Set<MemberDomain> invitMembers; // 推荐成功的人
	@JsonIgnore private Set<GoodsDomain> favoriteGoods;// 商品收藏夹
	@JsonIgnore private Set<CommentDomain> comments; //评论
	
	@PrePersist
	public void prePrePersist(){
		if(isAccountLocked == null){
			isAccountLocked = false;
		}
		if(loginFailureCount == null){
			loginFailureCount = 0;
		}
		if(isAccountEnabled == null){
			isAccountEnabled = true;
		}
		if(point == null){
			point = 0;
		}
		if(deposit == null){
			deposit = BigDecimal.ZERO;
		}
	}
	
	@Transient
	public void copyProperties(MemberDomain member){
		this.setMobile(member.getMobile());
		this.setEmail(member.getEmail());
		this.setName(member.getName());
		this.setZipCode(member.getZipCode());
		this.setAddress(member.getAddress());
		this.setSex(member.getSex());
	}
	
	/**
	 * 验证手机验证码
	 * @param code 验证码
	 * @return
	 */
	@Transient
	public String verifyMobileCode(String code){
		if(StringUtils.isBlank(smsVerifyCode) || StringUtils.isBlank(code)){
			return "手机验证码错误";
		}
		JSONObject codeInfo = JSONObject.fromObject(smsVerifyCode);
		long time = codeInfo.getLong("expired");
		if(System.currentTimeMillis() > time){
			return "手机验证码已过期";
		}
		if(!code.equals(codeInfo.getString("code"))){
			return "手机验证码错误";
		}
		return null;
	}
	
	/**
	 * 验证码是否过期
	 * @return
	 */
	@Transient
	public boolean isMobileCodeValid(){
		if(StringUtils.isBlank(smsVerifyCode)){
			return false;
		}
		JSONObject codeInfo = JSONObject.fromObject(smsVerifyCode);
		long time = codeInfo.getLong("expired");
		return System.currentTimeMillis() <= time;
	}
	
	/**
	 * 添加邮件验证码
	 * @param type 验证码类型
	 * @param code 验证码
	 */
	@Transient
	public void addEmailVerifyCode(Integer type, String code){
		JSONObject codeInfo = null;
		if(StringUtils.isBlank(emailVerifyCode)){
			codeInfo = new JSONObject();
		}else{
			codeInfo = JSONObject.fromObject(emailVerifyCode);
		}
		codeInfo.put(type, code);
		this.emailVerifyCode = codeInfo.toString();
	}
	
	/**
	 * 删除邮件验证码
	 * @param type 验证码类型
	 */
	@Transient
	public void removeEmailVerifyCode(Integer type){
		JSONObject codeInfo = null;
		if(StringUtils.isBlank(emailVerifyCode)){
			codeInfo = new JSONObject();
		}else{
			codeInfo = JSONObject.fromObject(emailVerifyCode);
		}
		codeInfo.remove(type.toString());
		this.emailVerifyCode = codeInfo.toString();
	}

	/**
	 * 验证邮件验证码
	 * @param type 验证码类型
	 * @param code 验证码
	 * @return
	 */
	@Transient
	public String verifyEmailCode(Integer type, String code){
		if(StringUtils.isBlank(emailVerifyCode)){
			return "验证码已失效";
		}
		JSONObject codeInfo = JSONObject.fromObject(emailVerifyCode);
		Object obj = codeInfo.get(type.toString());
		if(obj == null){
			return "验证码已失效";
		}
		return VerifyUtil.checkEmailVerify(obj.toString(), code, null);
	}

	/**
	 * 根据验证码类型获取邮件验证码
	 * @param type 验证码类型
	 * @return
	 */
	@Transient
	public String getEmailVerifyCode(Integer type){
		if(StringUtils.isBlank(emailVerifyCode)){
			return null;
		}
		JSONObject codeInfo = JSONObject.fromObject(emailVerifyCode);
		Object obj = codeInfo.get(type.toString());
		if(obj == null){
			return null;
		}
		return obj.toString();
	}

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public Integer getPoint() {
		return point;
	}

	public void setPoint(Integer point) {
		this.point = point;
	}

	public Integer getLoginFailureCount() {
		return loginFailureCount;
	}

	public void setLoginFailureCount(Integer loginFailureCount) {
		this.loginFailureCount = loginFailureCount;
	}

	public Boolean getIsAccountEnabled() {
		return isAccountEnabled;
	}

	public void setIsAccountEnabled(Boolean isAccountEnabled) {
		this.isAccountEnabled = isAccountEnabled;
	}

	public Boolean getIsAccountLocked() {
		return isAccountLocked;
	}

	public void setIsAccountLocked(Boolean isAccountLocked) {
		this.isAccountLocked = isAccountLocked;
	}

	public Date getLockedDate() {
		return lockedDate;
	}

	public void setLockedDate(Date lockedDate) {
		this.lockedDate = lockedDate;
	}

	public String getRegisterIp() {
		return registerIp;
	}

	public void setRegisterIp(String registerIp) {
		this.registerIp = registerIp;
	}

	public String getLoginIp() {
		return loginIp;
	}

	public void setLoginIp(String loginIp) {
		this.loginIp = loginIp;
	}

	public Date getLoginDate() {
		return loginDate;
	}

	public void setLoginDate(Date loginDate) {
		this.loginDate = loginDate;
	}

	public Boolean getSex() {
		return sex;
	}

	public void setSex(Boolean sex) {
		this.sex = sex;
	}

	public String getMobile() {
		return mobile;
	}

	public void setMobile(String mobile) {
		this.mobile = mobile;
	}

	public String getPhone() {
		return phone;
	}

	public void setPhone(String phone) {
		this.phone = phone;
	}

	public String getQq() {
		return qq;
	}

	public void setQq(String qq) {
		this.qq = qq;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	@ManyToOne(fetch=FetchType.LAZY)
	public AreaDomain getArea() {
		return area;
	}

	public void setArea(AreaDomain area) {
		this.area = area;
	}

	public String getAddress() {
		return address;
	}

	public void setAddress(String address) {
		this.address = address;
	}

	public String getZipCode() {
		return zipCode;
	}

	public void setZipCode(String zipCode) {
		this.zipCode = zipCode;
	}

	@ManyToOne(fetch=FetchType.LAZY)
	public MemberDomain getInviter() {
		return inviter;
	}

	public void setInviter(MemberDomain inviter) {
		this.inviter = inviter;
	}

	@OneToOne(fetch=FetchType.LAZY, mappedBy="member")
	public CartDomain getCart() {
		return cart;
	}

	public void setCart(CartDomain cart) {
		this.cart = cart;
	}

	@OneToMany(fetch=FetchType.LAZY, mappedBy="member")
	public Set<ReceiverDomain> getReceiverSet() {
		return receiverSet;
	}

	public void setReceiverSet(Set<ReceiverDomain> receiverSet) {
		this.receiverSet = receiverSet;
	}

	@OneToMany(fetch=FetchType.LAZY,mappedBy="inviter")
	public Set<MemberDomain> getInvitMembers() {
		return invitMembers;
	}

	public void setInvitMembers(Set<MemberDomain> invitMembers) {
		this.invitMembers = invitMembers;
	}

	@ManyToMany(fetch=FetchType.LAZY)
    @JoinTable(name = "b2c_favorite_goods", 
            joinColumns = {@JoinColumn(name = "member_id") }, 
            inverseJoinColumns = {@JoinColumn(name = "goods_id")})
	public Set<GoodsDomain> getFavoriteGoods() {
		return favoriteGoods;
	}

	public void setFavoriteGoods(Set<GoodsDomain> favoriteGoods) {
		this.favoriteGoods = favoriteGoods;
	}

	public String getEmailVerifyCode() {
		return emailVerifyCode;
	}

	public void setEmailVerifyCode(String emailVerifyCode) {
		this.emailVerifyCode = emailVerifyCode;
	}

	public String getSmsVerifyCode() {
		return smsVerifyCode;
	}

	public void setSmsVerifyCode(String smsVerifyCode) {
		this.smsVerifyCode = smsVerifyCode;
	}

	public BigDecimal getDeposit() {
		return deposit;
	}

	public void setDeposit(BigDecimal deposit) {
		this.deposit = deposit;
	}

	@OneToMany(fetch=FetchType.LAZY, mappedBy="member")
	public Set<CommentDomain> getComments() {
		return comments;
	}

	public void setComments(Set<CommentDomain> comments) {
		this.comments = comments;
	}

	public Date getBirthday() {
		return birthday;
	}

	public void setBirthday(Date birthday) {
		this.birthday = birthday;
	}
}
